<script>
import { defineComponent, ref, watch, computed } from 'vue';
import { transformStyleSize } from '../utils';

export default defineComponent({
  options: {
    // https://uniapp.dcloud.io/matter.html#mp
    virtualHost: true,
  },
  props: {
    items: Array,
    value: Array,
    index: Number,
    valueKey: String,
  },
  emits: ['selectItem'],
  setup(props, { emit }) {
    const currentOffset = ref(110);
    const selectVal = ref();
    const selectInd = ref();

    let start = 0;
    let newOffset = currentOffset.value;

    const colStyle = computed(() => {
      const s = `transform: translate3d(0, ${currentOffset.value}PX, 0)`;
      return transformStyleSize(s);
    });

    const onTouchstart = (e) => {
      selectVal.value = null;
      selectInd.value = null;
      start = e.touches[0].screenY;
      newOffset = currentOffset.value;
    };
    const onTouchmove = (e) => {
      if (!props.items.find((item) => !item.disabled)) return;
      const y = e.touches[0].screenY;
      if (y > start) {
        // 向上
        currentOffset.value = newOffset + (y - start);
      } else {
        // 向下
        currentOffset.value = newOffset - (start - y);
      }
    };
    const onTouchEnd = (items) => {
      if (!items?.find((item) => !item.disabled)) return;
      let i = Number(
        String(Math.floor(currentOffset.value / 44) - 2).replace(/\-/g, ''),
      );
      if (typeof selectInd.value === 'number') i = selectInd.value;

      if (i > props.items.length - 1) {
        i = props.items.length - 1;
      } else if (currentOffset.value > 110) {
        currentOffset.value = 110;
        i = 0;
      }
      if (items && items[i]?.disabled) {
        selectInd.value = i += 1;
        if (selectInd.value >= items.length) selectInd.value -= 2;
        onTouchEnd(items);
        return;
      }
      currentOffset.value = 110 - i * 44;
      let key = i;
      if (props.valueKey) key = items[i][props.valueKey];
      selectVal.value = key;
      emit('selectItem', { level: props.index, select: key, index: i });
    };

    const onClick = (item, index) => {
      if (item.disabled) return;
      selectInd.value = index;
      onTouchEnd(props.items);
    };

    watch(
      () => props.value,
      (val) => {
        let isData = false;
        if (val.length && val.some((s) => !!s)) isData = true;
        const list = [...val];
        if (isData && selectVal.value !== list[props.index]) {
          selectVal.value = list[props.index];
          const i = props.items.findIndex((item, i) => {
            if (props.valueKey) {
              return item[props.valueKey] === selectVal.value;
            } else {
              return i === selectVal.value;
            }
          });
          selectInd.value = i >= 0 ? i : 0;
          onTouchEnd(props.items);
        }
      },
      {
        immediate: true,
        deep: true,
      },
    );

    return {
      currentOffset,
      colStyle,
      onTouchstart,
      onTouchmove,
      onTouchEnd,
      onClick,
    };
  },
});
</script>

<template>
  <div
    class="fan-picker__box"
    @touchstart="onTouchstart"
    @touchmove.prevent="onTouchmove"
    @touchend="onTouchEnd(items)"
    @touchcancel="onTouchEnd(items)"
  >
    <div class="fan-picker__l" :style="colStyle">
      <div
        v-for="(item, i) in items"
        :key="i"
        class="fan-flex-center fan-picker__txt"
        :style="{ height: '44PX' }"
        @click="onClick(item, i)"
        :class="{ 'fan-picker__d': item.disabled }"
      >
        <div class="fan-ellipsis">
          {{ item.text }}
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="less">
.fan-picker {
  &__box {
    flex: 1;
    font-size: 16px;
    overflow: hidden;
    cursor: pointer;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
  }

  &__l {
    transition-duration: 300ms;
    transition-property: 2;
    transition-timing-function: cubic-bezier(0.23, 1, 0.68, 1);
  }

  &__txt {
    padding: 0 4px;
    color: #323233;
  }

  &__d {
    opacity: var(--fan-disabled-opacity);
  }
}
</style>
